<!--
 * @Descripttion: 单位树形结构
 * @msg1: 使用el-tree组件懒加载，具备增删改查功能
 * @msg2: 可对外抛出信息，发射事件为 toggleOrgId()
 * @msg3: 引入组件有 OrgAdd, OrgEdit, OrgDetail 
 * @version: 
 * @Author: yuanliutech
 * @Date: 2022-12-15 15:09:17
 * @LastEditors: yuanliutech@lwj
 * @LastEditTime: 2022-12-15 15:26:27
-->
<template>
  <div class="tree-container">
    <div class="header">
      <el-input
        placeholder="请输入内容"
        v-model="orgName"
        style="width: 200px"
        size="small"
        clearable
        @clear="searchClick"
      >
        <el-button
          slot="append"
          icon="el-icon-search"
          @click="searchClick"
        ></el-button>
      </el-input>
    </div>
    <div class="middle">
      <el-tree
        v-if="isTree"
        :data="dataTree"
        node-key="id"
        :props="defaultProps"
        :default-checked-keys="[firstInfo.id]"
        @node-click="handleNodeClick"
        :load="loadNode"
        lazy
        ref="refTree"
        :expand-on-click-node="false"
      >
        <div
          class="custom-tree-node"
          slot-scope="{ node, data }"
          @mouseenter="slideIn(data)"
          @mouseleave="slideAway(data)"
        >
          <span>{{ node.label }}</span>
          <div class="tree-node_ctrls" v-show="data.showCtrls">
            <i
              v-if="data.level <= 4"
              class="el-icon-circle-plus-outline"
              @click="addClick(data)"
            ></i>
            <i class="el-icon-delete" @click="delClick(data)"></i>
            <i class="el-icon-edit-outline" @click="editClick(data)"></i>
            <i class="el-icon-document" @click="detailClick(data)"></i>
          </div>
        </div>
      </el-tree>
    </div>
    <div class="footer">
      <div class="btn">
        <el-button icon="el-icon-plus" size="small" @click="addClick"
          >新增一级单位</el-button
        >
      </div>
    </div>
    <org-add
      ref="refAdd"
      :parentOrgInfo="parentOrgInfo"
      @updateTree="updateTree"
      @clearParentOrgInfo="clearParentOrgInfo"
    ></org-add>
    <org-edit
      ref="refEdit"
      :editOrgInfo="editOrgInfo"
      @updateTree="updateTree"
      @clearEditOrgInfo="clearEditOrgInfo"
    ></org-edit>
    <org-detail ref="refDetail" :detailOrgInfo="detailOrgInfo"></org-detail>
  </div>
</template>

<script>
import { reqOrgList, reqOrgLevel, reqOrgDel } from "@api/api.js";
import { mapState } from "vuex";
import OrgAdd from "./OrgAdd.vue";
import OrgEdit from "./OrgEdit.vue";
import OrgDetail from "./OrgDetail.vue";
export default {
  components: { OrgAdd, OrgEdit, OrgDetail },
  data() {
    return {
      isTree: true,
      dataTree: [],
      orgName: "",
      defaultProps: {
        children: "children",
        label: "orgName",
        isLeaf: "hasChildren",
        id: "id",
      },
      firstInfo: {}, //默认第一条信息
      parentOrgInfo: {}, //父单位信息--新增用
      editOrgInfo: {}, //修改一条单位信息
      detailOrgInfo: {}, //详情
    };
  },
  computed: {
    ...mapState(["user"]),
  },
  mounted() {},
  methods: {
    // 点击新增一级单位
    addClick(data) {
      if (data.id) {
        // 新增下级单位
        this.$refs.refAdd.dialogVisible = true;
        this.parentOrgInfo = JSON.parse(JSON.stringify(data));
      } else {
        // 新增一级单位
        this.$refs.refAdd.dialogVisible = true;
      }
    },
    // 点击一条
    handleNodeClick(data) {
      let params = {
        orgId: data.id,
        orgName: data.orgName,
      };
      this.$emit("toggleOrgId", params);
    },

    // 树节点懒加载
    async loadNode(node, resolve) {
      if (node.level == 0) {
        // 如果是一级单位
        let params = {
          tenantId: this.user.tenantId,
          userId: this.user.userId,
          roleName: this.user.roleName,
          orgName: this.orgName,
        };
        let res = await reqOrgList(params);
        if (res.code !== 20000) return this.$modal.notifyWarning(res.message);
        let rows = res.data.rows;
        this.$emit("toggleOrgId", {
          orgId: rows[0].id,
          orgName: rows[0].orgName,
        });
        this.firstInfo = rows[0];
        rows.forEach((item) => {
          if (item.hasChildren === 1) {
            item.hasChildren = false;
          } else {
            item.hasChildren = true;
          }
        });
        return resolve(rows);
      } else {
        // 否则是下级单位
        let res = await reqOrgLevel(node.data.id);
        if (res.code !== 20000) return this.$modal.notifyWarning(res.message);
        let rows = res.data.rows;
        rows.forEach((item) => {
          if (item.hasChildren === 1) {
            item.hasChildren = false;
          } else {
            item.hasChildren = true;
          }
        });
        return resolve(rows);
      }
    },
    // 查询单位
    searchClick() {
      this.updateOrg();
    },
    // 更新整个单位
    updateOrg() {
      this.isTree = false;
      setTimeout(() => {
        this.isTree = true;
      }, 0);
    },
    // 局部更新单位
    updateLoadNode() {
      let key = this.$refs.refTree.getCurrentKey();
      // console.log(key);
      if (key) {
        // 如果是下级单位更新
        let node = this.$refs.refTree.getNode(key);
        node.parent.loaded = false;
        node.parent.expand();
      } else {
        // 否则是一级单位更新
        this.updateOrg();
      }
    },
    // 滑动进去一条
    slideIn(data) {
      this.$set(data, "showCtrls", true);
    },
    slideAway(data) {
      this.$set(data, "showCtrls", false);
    },
    // 点击编辑
    editClick(data) {
      this.$refs.refEdit.dialogVisible = true;
      this.editOrgInfo = JSON.parse(JSON.stringify(data));
    },
    // 查看详情
    detailClick(data) {
      this.$refs.refDetail.dialogVisible = true;
      this.detailOrgInfo = JSON.parse(JSON.stringify(data));
    },
    // 新增、编辑成功后修改树形列表
    updateTree() {
      this.updateLoadNode();
      this.parentOrgInfo = {};
      this.editOrgInfo = {};
    },
    // 清除新增数据
    clearParentOrgInfo() {
      this.parentOrgInfo = {};
    },
    // 清除编辑数据
    clearEditOrgInfo() {
      this.editOrgInfo = {};
    },
    // 删除一个单位
    delClick(data) {
      let { id, hasChildren } = data;
      if (!hasChildren)
        return this.$modal.notifyWarning("存在下级单位机构，不能删除");
      this.$confirm("此操作将永久删除该单位, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(async () => {
          let res = await reqOrgDel(id);
          if (res.code !== 20000) return this.$modal.notifyWarning(res.message);
          this.$modal.notifySuccess("删除成功");
          this.updateTree();
        })
        .catch(() => {});
    },
  },
};
</script>

<style scoped lang="less">
.tree-container {
  width: 100%;
  height: 100%;

  .header {
    position: relative;
    height: 65px;
    border-bottom: 1px solid @primaryBorderColor;
    display: flex;
    align-items: center;
    justify-content: space-around;

    .el-icon-search {
      color: @primaryBorderColor;
      font-size: 20px;
    }
  }
  .middle {
    height: calc(100% - 65px - 70px);
    overflow: hidden;
    overflow-y: scroll;

    .custom-tree-node {
      width: 100%;
      display: flex;
      align-items: center;
      justify-content: space-between;

      .tree-node_ctrls {
        position: absolute;
        right: 0;
        width: 30%;
        text-align: right;
        padding-right: 10px;
        // background-color: pink;

        i {
          color: #aaa;
          font-size: 20px;
          margin-left: 10px;
          &:hover {
            color: #fff;
          }
        }
      }
    }
    ::v-deep .el-tree {
      height: 100%;
      background: @primaryHeaderBgcolor;
      box-sizing: border-box;
      padding: 12px 10px;
      color: @primaryThemeTxtColor;
      overflow: hidden;
      overflow-y: scroll;
    }

    ::v-deep .el-tree-node__content:hover {
      background: @paginationBgcolor !important;
      border-radius: 4px;
    }

    ::v-deep .el-tree-node.is-current > .el-tree-node__content {
      background-color: #7367f0 !important;
      border-radius: 4px;
    }

    ::v-deep .is-current > .el-tree-node__content > .el-tree-node__label {
      color: #f0f0f0;
    }
  }
  .footer {
    position: relative;
    width: 100%;
    height: 100px;
    display: flex;
    align-content: center;
    justify-content: center;
    border-top: 1px solid @primaryBorderColor;
    .btn {
      margin-top: 15px;
    }
  }
}

::v-deep .el-input {
}

::v-deep .el-input__inner {
}
</style>